package com.xlh.listener;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.xlh.service.system.OperationService;
import com.xlh.util.SpringContextUtil;

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * 流水登陆任务
 * <p>
 * Created by lx on 2018/7/4.
 */
public class OperationLoginTask implements Delayed, Runnable {

    private static OperationService operationService = SpringContextUtil.getBean(OperationService.class);

    private static final int MAX_RETRY_NUM = 5;

    /**
     * 流水额外表id
     */
    private Long operationExtendId;

    /**
     * 过期时间
     */
    private long expireTime;

    /**
     * 重试次数
     */
    private int retryNum;

    public OperationLoginTask(Long operationExtendId, int retryNum) {
        this.operationExtendId = operationExtendId;
        this.expireTime = DateUtil.currentSeconds() + NumberUtil.pow(2, retryNum).longValue();
        this.retryNum = retryNum;
    }

    /**
     * 返回与此对象相关的剩余延迟时间，以给定的时间单位表示
     */
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(expireTime - DateUtil.currentSeconds(), TimeUnit.SECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        if (o == this) {
            return 0;
        }
        if (o instanceof OperationLoginTask) {
            OperationLoginTask other = (OperationLoginTask) o;
            if (expireTime < other.expireTime) {
                return -1;
            } else if (expireTime > other.expireTime) {
                return 1;
            }
        }
        return 0;
    }

    @Override
    public void run() {

        int num = retryNum + 1;

        boolean updateFlag = operationService.updateOperationExtend(operationExtendId);

        if (updateFlag || (!updateFlag && num > MAX_RETRY_NUM)) return;

        // 如果失败，就重试
        OperationLoginListener.getDelayQueue().put(new OperationLoginTask(operationExtendId, num));

    }
}
